5.01. Справочник по Ext JS
Общая архитектура ExtJS
ExtJS — это полноценный JavaScript-фреймворк для создания сложных веб-приложений с богатым пользовательским интерфейсом. Он предоставляет систему компонентов, управление данными, маршрутизацию, шаблоны и инструменты разработки.
Ключевые принципы:
- Все элементы интерфейса — экземпляры классов, наследуемых от
Ext.Component. - Компоненты могут содержать другие компоненты через систему контейнеров (
Ext.container.Container). - Управление жизненным циклом компонентов осуществляется через события:
initComponent,afterRender,destroy. - Поддержка реактивности через связывание данных (
bind) и MVVM-архитектуру. - Макеты (
layout) определяют позиционирование и размеры дочерних элементов.
Базовый класс: Ext.Component
Все виджеты и контейнеры наследуются от Ext.Component.
Основные конфигурации:
| Конфиг | Тип | Описание | Примеры значений |
|---|---|---|---|
id | String | Уникальный идентификатор компонента | 'mainPanel' |
itemId | String | Локальный идентификатор для поиска внутри контейнера | 'searchField' |
cls | String | CSS-класс, добавляемый к корневому элементу | 'custom-panel-style' |
style | String / Object | Инлайновые стили | { color: 'red', padding: '10px' } |
hidden | Boolean | Скрывает компонент без удаления из DOM | true, false |
disabled | Boolean | Отключает взаимодействие с компонентом | true, false |
renderTo | String / HTMLElement | Контейнер, в который рендерится компонент при создании | 'app-container', document.body |
width / height | Number / String | Размеры компонента | 300, '100%' |
minWidth / maxWidth | Number | Ограничения по ширине | 200, 800 |
flex | Number | Используется в layout типа hbox или vbox | 1, 2 |
tooltip | String / Object | Всплывающая подсказка | 'Нажмите для сохранения' |
ui | String | Тема оформления (если определена) | 'light', 'dark' |
Основные методы:
show()— делает компонент видимым.hide()— скрывает компонент.enable()— включает компонент.disable()— отключает компонент.destroy()— удаляет компонент и освобождает ресурсы.up([selector])— ищет ближайший родительский компонент по селектору.down([selector])— ищет первый дочерний компонент по селектору.query([selector])— возвращает массив компонентов по селектору.
Селекторы для поиска:
- По
xtype:'button' - По
itemId:'#myButton' - По
id:'myButton'(без решётки) - По классу:
'.my-class' - По атрибуту:
'[text=Save]'
Контейнеры (Ext.container.Container и наследники)
Контейнеры управляют дочерними компонентами и применяют макеты.
Общие конфигурации контейнера:
| Конфиг | Тип | Описание |
|---|---|---|
items | Array / Object | Массив или одиночный компонент для отображения |
layout | String / Object | Тип макета или его конфигурация |
defaults | Object | Конфигурация по умолчанию для всех дочерних элементов |
autoDestroy | Boolean | Автоматическое уничтожение дочерних компонентов при удалении контейнера |
scrollable | Boolean / String | Полосы прокрутки |
Основные типы контейнеров:
1. Ext.panel.Panel
Панель с заголовком, тулбаром, телом и футером.
Дополнительные конфигурации:
title— заголовок панели.header— объект илиfalseдля скрытия заголовка.tools— массив кнопок в правом верхнем углу (например, закрыть, свернуть).tbar/bbar— верхний и нижний тулбары.collapsible— возможность сворачивания.collapsed— начальное состояние свёрнутости.frame— рамка вокруг панели (стилизация).bodyPadding— отступ внутри тела панели.
Пример tools:
tools: [{
type: 'close',
handler: function() { /* закрытие */ }
}]
2. Ext.window.Window
Модальное или немодальное окно поверх интерфейса.
Особенности:
- Наследуется от
Panel. - Поддерживает перетаскивание (
draggable: trueпо умолчанию). - Может быть модальным (
modal: true). - Имеет кнопки
OK/Cancelчерезbuttonsилиfbar.
Конфигурации:
modal— затемнение фона и блокировка взаимодействия.closable— кнопка закрытия в заголовке.resizable— возможность изменения размера.constrain— ограничение перемещения в пределах viewport.animateTarget— элемент, от которого анимируется появление.
3. Ext.tab.Panel
Контейнер с вкладками.
Конфигурации:
tabPosition— положение вкладок:'top','bottom','left','right'.activeTab— индекс или ссылка на активную вкладку.plain— упрощённый стиль без рамок.deferredRender— отложенная отрисовка невидимых вкладок.
У вкладки (дочернего компонента):
title— название вкладки.iconCls— CSS-класс иконки.closable— кнопка закрытия вкладки.
4. Ext.container.Viewport
Контейнер, занимающий всё окно браузера. Автоматически рендерится в document.body.
- Не требует
renderTo. - Реагирует на изменение размера окна.
Макеты (layout)
Макеты управляют расположением и размерами дочерних компонентов.
Основные типы макетов:
fit
- Отображает один дочерний компонент, растягивая его на всю площадь контейнера.
- Используется в модальных окнах, карточках.
hbox / vbox
- Горизонтальное (
hbox) или вертикальное (vbox) выравнивание. - Поддерживает
align,pack,flex.
Конфигурации:
align— выравнивание по поперечной оси:'start','center','stretch','end'.pack— распределение по главной оси:'start','center','end','justify'.flex— пропорциональное распределение пространства.
Пример:
layout: {
type: 'hbox',
align: 'stretch',
pack: 'center'
}
border
- Делит контейнер на регионы:
north,south,west,east,center. - Только один дочерний элемент может иметь
region: 'center'. - Элементы с
region: 'west'или'east'могут быть сворачиваемыми (collapsible: true).
card
- Отображает один "карточный" элемент за раз.
- Переключение через
setActiveItem().
anchor
- Позволяет задавать размеры относительно родителя с помощью
anchorу дочерних элементов. - Пример:
anchor: '100% 50%'— ширина 100%, высота 50%.
table
- Располагает элементы в сетке, как HTML-таблица.
- Использует
columnsиtdAttrs.
Формы и поля ввода (Ext.form.*)
Формы в ExtJS строятся на базе Ext.form.Panel, который автоматически управляет сбором, валидацией и отправкой данных.
Базовый класс: Ext.form.field.Base
Все поля наследуются от этого класса и поддерживают общие свойства:
| Конфиг | Тип | Описание | Примеры |
|---|---|---|---|
fieldLabel | String | Подпись к полю | 'Имя пользователя' |
name | String | Имя поля для отправки данных | 'username' |
value | Any | Начальное значение | 'admin' |
allowBlank | Boolean | Разрешает пустое значение | false |
blankText | String | Сообщение при пустом значении | 'Поле обязательно' |
validator | Function | Пользовательская функция валидации | function(val) { return val.length > 3 ? true : 'Минимум 4 символа'; } |
validateOnBlur | Boolean | Запускать валидацию при потере фокуса | true |
validateOnChange | Boolean | Валидация при каждом изменении | true |
msgTarget | String | Где отображать ошибку | 'side', 'under', 'qtip' |
inputAttrTpl | String | Шаблон атрибутов HTML-элемента | '<tpl if="required">required</tpl>' |
Основные типы полей:
Ext.form.field.Text
- Однострочное текстовое поле.
- Дополнительные конфиги:
emptyText,maxLength,enforceMaxLength.
Ext.form.field.TextArea
- Многострочное поле.
- Поддерживает
grow(автоматическое расширение по высоте).
Ext.form.field.Number
- Только числа.
- Конфиги:
minValue,maxValue,decimalPrecision,step.
Ext.form.field.Date
- Выбор даты через календарь.
format— формат отображения ('d.m.Y').submitFormat— формат при отправке.
Ext.form.field.ComboBox
- Выпадающий список с возможностью ввода.
- Связывается с
Ext.data.Store. - Ключевые конфиги:
displayField— поле для отображения.valueField— поле для значения.queryMode—'local'или'remote'.typeAhead— автозавершение.forceSelection— разрешает только выбор из списка.editable— можно ли вводить текст.
Ext.form.field.Checkbox / Ext.form.field.Radio
- Чекбоксы и радиокнопки.
- Группировка радио через
name.
Ext.form.field.File
- Выбор файла.
- Поддержка
multiple: true. - Не отправляет данные напрямую — требует FormData или iframe в старых версиях.
Ext.form.FieldContainer
- Контейнер для группировки полей без визуального поля ввода.
- Полезен для кастомных компонентов (например, «Диапазон дат» из двух полей).
Таблицы: Ext.grid.Panel
Один из самых мощных компонентов ExtJS — грид для отображения табличных данных.
Основные конфигурации:
| Конфиг | Описание |
|---|---|
store | Экземпляр Ext.data.Store с данными |
columns | Массив описаний колонок |
selModel | Модель выделения: 'rowmodel', 'cellmodel', 'checkboxmodel' |
plugins | Расширения: редактирование, drag-and-drop |
viewConfig | Настройки отрисовки строк |
enableColumnHide | Разрешить скрывать колонки через меню |
enableColumnMove | Разрешить перетаскивание колонок |
enableColumnResize | Изменение ширины колонок |
columnLines | Вертикальные линии между колонками |
rowLines | Горизонтальные линии между строками |
Колонки (columns):
Каждая колонка — объект с конфигурацией.
| Свойство | Описание |
|---|---|
text | Заголовок колонки |
dataIndex | Имя поля в модели данных |
width | Ширина в пикселях |
flex | Пропорциональная ширина |
sortable | Сортировка по клику |
renderer | Функция для кастомного отображения ячейки |
editor | Поле для inline-редактирования |
hidden | Скрыта ли колонка |
menuDisabled | Отключено ли контекстное меню колонки |
Пример колонки:
{
text: 'Статус',
dataIndex: 'status',
renderer: function(value) {
return value === 1 ? 'Активен' : 'Неактивен';
},
editor: {
xtype: 'combobox',
store: statusStore,
displayField: 'name',
valueField: 'id'
}
}
Редактирование в гриде:
- Включается через плагин
celleditingилиrowediting. - При двойном клике или нажатии Enter открывается редактор.
- Поддерживает все стандартные поля ввода.
Панели инструментов грида:
dockedItemsсxtype: 'pagingtoolbar'— пагинация.topBar/bottomBar— кастомные панели.
Деревья: Ext.tree.Panel
Используется для иерархических данных.
Особенности:
- Хранит данные в
Ext.data.TreeStore. - Каждый узел — экземпляр
Ext.data.Modelс полями:text,leaf,expanded,children. - Поддерживает lazy-loading через
proxy.
Конфигурации:
rootVisible— показывать корневой узел.useArrows— использовать стрелки вместо +/-.lines— отображать соединительные линии.singleExpand— раскрывать только одну ветку за раз.
События:
itemclick,itemdblclickbeforeitemexpand,itemexpandcheckchange— при использовании чекбоксов (checked: trueв узле)
Диаграммы и графики: Ext.chart.CartesianChart, Ext.chart.PolarChart
ExtJS включает встроенный движок визуализации на основе SVG/VML.
Типы диаграмм:
- Линейная (
line) - Столбчатая (
bar,column) - Круговая (
pie) - Радар (
radar) - Площадная (
area)
Основные компоненты диаграммы:
axes— оси X и Y (или радиальная/угловая для Polar)series— наборы данныхlegend— легендаinteractions— взаимодействия: zoom, pan, tooltip
Пример серии:
series: [{
type: 'line',
xField: 'month',
yField: 'sales',
title: 'Продажи',
marker: { radius: 4 }
}]
Особенности:
- Поддержка анимации.
- Адаптивность под размер контейнера.
- Экспорт в изображение (через
chart.save()в новых версиях).
🔹 Система данных: Ext.data.*
ExtJS предоставляет мощную систему управления данными через модели, хранилища и прокси.
1. Модель (Ext.data.Model)
Модель описывает структуру одной записи (например, пользователя, товара).
Основные конфигурации:
| Конфиг | Тип | Описание |
|---|---|---|
fields | Array | Описание полей записи |
idProperty | String | Имя поля, используемого как уникальный идентификатор |
validators | Object | Правила валидации полей |
proxy | Object / String | Прокси для загрузки/сохранения |
hasMany / belongsTo | Object | Отношения «один ко многим», «многие к одному» |
Пример модели:
Ext.define('App.model.User', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int' },
{ name: 'name', type: 'string' },
{ name: 'email', type: 'string' },
{ name: 'active', type: 'boolean', defaultValue: true }
],
idProperty: 'id'
});
Типы полей:
'string''int''float''boolean''date'— с опциональнымdateFormat'auto'— без преобразования
Валидация:
validators: {
email: 'email',
name: { type: 'length', min: 2 }
}
2. Хранилище (Ext.data.Store)
Хранилище управляет коллекцией моделей.
Основные конфигурации:
| Конфиг | Описание |
|---|---|
model | Класс модели |
data | Начальные данные (массив объектов) |
proxy | Прокси для загрузки/сохранения |
autoLoad | Загружать данные автоматически при создании |
pageSize | Размер страницы для пагинации |
remoteSort | Сортировка на сервере |
remoteFilter | Фильтрация на сервере |
sorters | Массив правил сортировки |
filters | Массив фильтров |
Пример хранилища:
Ext.create('Ext.data.Store', {
model: 'App.model.User',
autoLoad: true,
proxy: {
type: 'ajax',
url: '/api/users',
reader: { type: 'json', rootProperty: 'data' }
}
});
Методы хранилища:
load()— загрузка данныхreload()— повторная загрузка с теми же параметрамиsync()— отправка изменений на серверadd(record)— добавление записиremove(record)— удалениеfindExact(field, value)— поиск по точному совпадениюfilter(filters)— применение фильтровclearFilter()— сброс фильтров
3. Прокси (Ext.data.proxy.*)
Прокси определяют, откуда и как загружаются/сохраняются данные.
Основные типы:
ajax— HTTP-запросы (GET/POST)rest— RESTful API с методами GET/POST/PUT/DELETEmemory— данные хранятся в памятиlocalstorage— сохранение вlocalStorageбраузераsessionstorage— сохранение вsessionStorage
Конфигурация прокси:
proxy: {
type: 'rest',
url: '/api/users',
reader: {
type: 'json',
rootProperty: 'items',
totalProperty: 'total'
},
writer: {
type: 'json',
writeAllFields: true
}
}
4. Читатели и записыватели (reader, writer)
Reader:
json— парсинг JSONxml— парсинг XMLarray— массивы
Ключевые свойства:
rootProperty— путь к массиву данныхtotalProperty— общее количество записей (для пагинации)successProperty— поле, указывающее на успех операции
Writer:
json— отправка данных в формате JSONform— отправка какapplication/x-www-form-urlencoded
Ключевые свойства:
writeAllFields— отправлять все поля, даже неизменённыеallowSingle— разрешить отправку одиночной записи без массива
События (Events)
ExtJS использует систему событий на основе Ext.util.Observable.
Основные принципы:
- Все компоненты и хранилища наследуют систему событий.
- Подписка через
on()илиlisteners. - Возможность отмены действия через
return falseв обработчике (если событие отменяемое).
Распространённые события компонентов:
click,dblclickbeforedestroy,destroyshow,hideresizeafterrender
События формы:
validitychange— изменение состояния валидностиfieldvaliditychange
События грида:
itemclick,itemdblclickselectionchangeedit— завершение редактирования ячейкиbeforeedit— возможность отменить редактирование
События хранилища:
load— после загрузки данныхbeforeload— до запросаupdate— изменение записиadd,removewrite— после успешной отправки на сервер
Глобальные события:
Ext.onReady()— выполнение кода после загрузки DOM и фреймворкаExt.getBody().on(...)— работа с DOM-событиями
Архитектура приложения: MVC и MVVM
MVC (Model-View-Controller)
- Model — данные (
Ext.data.Model) - View — компоненты интерфейса
- Controller — логика, обработка событий
Контроллер регистрирует слушателей через control:
control: {
'button[action=save]': { click: 'onSaveClick' }
}
MVVM (Model-View-ViewModel)
- Вводит
ViewModel— контейнер данных, привязанных к View. - Поддерживает двустороннее связывание (
bind).
Пример:
{
xtype: 'textfield',
bind: '{user.name}'
}
В контроллере или представлении:
viewModel: {
data: {
user: { name: 'John' }
}
}
Изменение user.name автоматически обновляет поле, и наоборот.
Утилиты и вспомогательные классы
Ext.Array
each(array, fn)contains(array, item)remove(array, item)merge(arr1, arr2)
Ext.Object
toArray(obj)getKey(obj, value)isEmpty(obj)
Ext.String
format('Hello {0}', 'World')escapeRegex(str)capitalize(str)
Ext.Date
parse(dateString, format)format(date, format)add(date, interval, amount)
Ext.Function
defer(fn, delay, scope, args)createBuffered(fn, buffer, scope)
Инструменты разработчика
Sencha Cmd
- Командная строка для сборки, минификации, темизации.
- Генерация приложений, контроллеров, моделей.
- Поддержка тем через SASS.
DevTools Integration
- Расширение Sencha Inspector для Chrome — позволяет:
- Просматривать дерево компонентов
- Анализировать хранилища
- Отслеживать события
- Изменять свойства в реальном времени
Отладка
console.log(component.up())— исследование иерархииcomponent.el.dom— доступ к DOM-элементуstore.getRange()— просмотр текущих записей
Темы и стилизация
-
ExtJS использует Sass для тем.
-
Базовые темы:
theme-classic,theme-neptune,theme-triton,theme-material. -
Кастомизация через переопределение переменных:
$panel-header-background-color: #333;
$button-default-ui-background-color: #007bff; -
Каждый компонент поддерживает
ui-конфигурацию для переключения стилей:{ xtype: 'button', text: 'Primary', ui: 'primary' }
Drag-and-Drop (DnD)
ExtJS включает встроенную поддержку перетаскивания через Ext.dd.*.
Основные компоненты:
Ext.dd.DragSource— элемент, который можно перетаскивать.Ext.dd.DropTarget— область, в которую можно сбросить.Ext.grid.plugin.DragDrop— плагин для грида, позволяющий перетаскивать строки.
Пример для грида:
plugins: {
ptype: 'gridviewdragdrop',
dragGroup: 'myGroup',
dropGroup: 'myGroup'
}
События DnD:
beforedrop— возможность отменить сброс.drop— обработка успешного сброса.dragstart,dragover,dragend
Кастомный DnD:
Для произвольных элементов используется Ext.dd.DD или Ext.dd.DDProxy.
Шаблоны: Ext.XTemplate
Позволяют гибко формировать HTML на основе данных.
Возможности:
- Условия (
<tpl if="...">) - Циклы (
<tpl for=".">) - Форматирование через функции
- Поддержка массивов и вложенных объектов
Пример:
var tpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="user {active: "active" : "inactive"}">',
'<h3>{name}</h3>',
'<p>Email: {[this.formatEmail(values.email)]}</p>',
'</div>',
'</tpl>',
{
formatEmail: function(email) {
return email ? email.toLowerCase() : '—';
}
}
);
Использование:
- В
Ext.view.View(DataView) - В
rendererколонок грида - В
tplсвойстве компонентов
Создание кастомных компонентов
Расширение существующих компонентов — основной способ кастомизации.
Базовый шаблон:
Ext.define('MyApp.view.CustomButton', {
extend: 'Ext.button.Button',
xtype: 'custombutton',
config: {
customColor: '#000'
},
applyCustomColor: function(color) {
this.el.setStyle('color', color);
return color;
},
initialize: function() {
this.callParent();
// Дополнительная инициализация
}
});
Рекомендации:
- Использовать
xtypeдля регистрации. - Разделять логику и представление.
- Использовать
configдля управляемых свойств с геттерами/сеттерами. - Вызывать
callParent()при переопределении методов.
Производительность
Оптимизация гридов:
- Использовать
bufferedRenderer: trueдля больших наборов данных. - Ограничивать количество отображаемых колонок.
- Избегать сложных
rendererв каждой ячейке. - Использовать
rowexpanderвместо вложенных гридов, если возможно.
Оптимизация форм:
- Группировать поля в
FieldSetтолько при необходимости. - Откладывать создание невидимых вкладок (
deferredRender: true).
Общие практики:
- Минимизировать количество DOM-элементов.
- Уничтожать неиспользуемые компоненты (
destroy()). - Использовать
itemIdвместоidдля локального поиска. - Избегать глубоких вложенности контейнеров.
Тестирование
Подходы:
- Unit-тесты: Jasmine + Karma (через Sencha Cmd).
- Интеграционные тесты: Siesta (официальный инструмент Sencha).
- Ручное тестирование: через DevTools и Sencha Inspector.
Советы:
- Тестируйте хранилища отдельно от UI.
- Мокайте прокси для изоляции данных.
- Проверяйте состояние компонентов после событий.
Полный список xtype
| xtype | Класс |
|---|---|
component | Ext.Component |
container | Ext.container.Container |
panel | Ext.panel.Panel |
window | Ext.window.Window |
form | Ext.form.Panel |
fieldset | Ext.form.FieldSet |
textfield | Ext.form.field.Text |
textarea | Ext.form.field.TextArea |
numberfield | Ext.form.field.Number |
datefield | Ext.form.field.Date |
timefield | Ext.form.field.Time |
checkbox | Ext.form.field.Checkbox |
radio | Ext.form.field.Radio |
combobox | Ext.form.field.ComboBox |
filefield | Ext.form.field.File |
displayfield | Ext.form.field.Display |
button | Ext.button.Button |
splitbutton | Ext.button.Split |
cycle | Ext.button.Cycle |
grid | Ext.grid.Panel |
tree | Ext.tree.Panel |
dataview | Ext.view.View |
tabpanel | Ext.tab.Panel |
viewport | Ext.container.Viewport |
toolbar | Ext.toolbar.Toolbar |
pagingtoolbar | Ext.toolbar.Paging |
menubar | Ext.menu.Bar |
menu | Ext.menu.Menu |
colorpicker | Ext.picker.Color |
datepicker | Ext.picker.Date |
slider | Ext.slider.Single |
multislider | Ext.slider.Multi |
chart | Ext.chart.CartesianChart |
polar | Ext.chart.PolarChart |
Полный список доступен в официальной документации ExtJS 7.0 Classic Toolkit.
Поддержка браузеров (ExtJS 7.x Classic)
| Браузер | Поддержка |
|---|---|
| Chrome | Полная |
| Firefox | Полная |
| Safari | Полная (macOS/iOS) |
| Edge (Chromium) | Полная |
| Edge (Legacy) | Не поддерживается |
| Internet Explorer | IE11 (только в Classic Toolkit) |
Modern Toolkit не поддерживает IE11.
Лицензирование
- GPLv3 — для открытых проектов.
- Коммерческая лицензия — для проприетарного ПО.
- Ext Core — MIT-лицензия (устаревшая часть, не используется в новых версиях).
Использование ExtJS в коммерческом продукте без лицензии нарушает условия Sencha.